<?php

declare(ENCODING = 'UTF-8');

/*                                                                        *
 * This script is part of the TYPO3 project - inspiring people to share!  *
 *                                                                        *
 * TYPO3 is free software; you can redistribute it and/or modify it under *
 * the terms of the GNU General Public License version 2 as published by  *
 * the Free Software Foundation.                                          *
 *                                                                        *
 * This script is distributed in the hope that it will be useful, but     *
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *	
 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General      *
 * Public License for more details.                                       *
 *                                                                        */	

/**
 * @package auxo
 * @subpackage Web
 * @version $Id$
 */

/**	
 * The Web Response
 * 
 * This class offers serveral methods to create a web response. 
 *	
 * @package auxo
 * @subpackage Web	
 * @version $Id$	
 * @copyright Copyright belongs to the respective authors
 * @author Andreas.Horn@extronaut.de
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License, version 2
 */
 class tx_auxo_Response {

 	/**
 	 * Response Status Code
 	 *
 	 * @var string
 	 */
 	protected $statusCode = 200;

 	/**
 	 * Response Text to corresponding Status Code
 	 *
 	 * @var string
 	 */
 	protected $statusText = 'OK';

 	/**
 	 * List of allowed HTTP Status Codes with Text
 	 *
 	 * @var array
 	 */
    protected $httpStatus = array(
			      '100' => 'Continue',
			      '101' => 'Switching Protocols',
			      '200' => 'OK',
			      '201' => 'Created',
			      '202' => 'Accepted',
			      '203' => 'Non-Authoritative Information',
			      '204' => 'No Content',
			      '205' => 'Reset Content',
			      '206' => 'Partial Content',
			      '300' => 'Multiple Choices',
			      '301' => 'Moved Permanently',
			      '302' => 'Found',
			      '303' => 'See Other',
			      '304' => 'Not Modified',
			      '305' => 'Use Proxy',
			      '306' => '(Unused)',
			      '307' => 'Temporary Redirect',
			      '400' => 'Bad Request',
			      '401' => 'Unauthorized',
			      '402' => 'Payment Required',
			      '403' => 'Forbidden',
			      '404' => 'Not Found',
			      '405' => 'Method Not Allowed',
			      '406' => 'Not Acceptable',
			      '407' => 'Proxy Authentication Required',
			      '408' => 'Request Timeout',
			      '409' => 'Conflict',
			      '410' => 'Gone',
			      '411' => 'Length Required',
			      '412' => 'Precondition Failed',
			      '413' => 'Request Entity Too Large',
			      '414' => 'Request-URI Too Long',
			      '415' => 'Unsupported Media Type',
			      '416' => 'Requested Range Not Satisfiable',
			      '417' => 'Expectation Failed',
			      '500' => 'Internal Server Error',
			      '501' => 'Not Implemented',
			      '502' => 'Bad Gateway',
			      '503' => 'Service Unavailable',
			      '504' => 'Gateway Timeout',
			      '505' => 'HTTP Version Not Supported',
			  );
 	
 	/**
 	 * Array of HTTP Headers
 	 * 
 	 * @var array
 	 */
 	protected $httpHeaders = array();

 	/**
 	 * Content type of this response 	
 	 * 
 	 * @var string 
 	 */
 	protected $contentType = '';
 	
 	/**
 	 * Response Content as String
 	 *
 	 * @var string
 	 */
	protected $content = '';
	
	/**
	 * Explicit set view name
	 *
	 * @var string
	 */
	protected $viewname = '';

	/**
	 * Builds an instance that represents an web reponse 
	 *
	 */
	public function __construct(tx_auxo_ExtensionEnvironment $environment) {
		$this->environment = $environment;
	}
	
 	/**
	 * Generates an URL with given parameters
	 *
	 * If no parameters are given an URL to the current page is created.
	 * 
	 * @param array $actions array of URL parameters 
	 * @param boolean $htmlspecial 
	 * @return string $url generated URL
	 */
	public function generateURL($actions=array(), $htmlspecial=true) {
		$url = tx_div::makeInstance('tx_lib_link');
        // set target page either by given parameter array or as current page
        $url->destination($actions['pageId'] ? $actions['pageId'] : $GLOBALS['TSFE']->id);
        // TODO link attribute designator is always set equal current running extension
        // and needs to be more flexibel
        $url->designator($this->environment->getExtension());
        if (count($actions) > 0) {
           $url->parameters($actions);
        }
        $url->noHash();
        return t3lib_div::locationHeaderUrl($url->makeURL($htmlspecial));		
	}	
	
	
	/**
	 * Adds a script or coding to the HTML header of the current response
   	 *
   	 * @param string $path
     * @param string $code
     * @param string $type
     * @return void
     */
	public function addHeaderScript($path='', $code='', $type='text/javascript') {
		if ($path) {
	      	$options['src'] = $path;
	      	$code = ' ';
 		}
      	$options['type'] = $type;
      	$GLOBALS['TSFE']->additionalHeaderData[$this->controller->getExtension()].= tx_auxo_aui_helper::getTag('script', $options, $code);
	}  
	
	/**
	 * Redirects to an URL e.g. http://www.hamburg.de
	 *
	 * @param string $url url to redirect to 
	 * @param int $delay seconds to wait before redirect to url
	 * @param int $statusCode status code that should be used to redirect
	 */
	public function redirect($url, $delay = 0, $statusCode = 302) {
		$this->clearHttpHeaders();
    	$this->setStatusCode($statusCode);
    	$this->setHttpHeader('Location', $url);
    	$this->setContent(sprintf('<html><head><meta http-equiv="refresh" content="%d;url=%s"/></head></html>', $delay, htmlentities($url, ENT_QUOTES, 'utf-8')));
      	$this->sendHttpHeaders();
    	$this->sendContent();		
	}
	
   /**
    * Sets response status code.
    *
    * @param string HTTP status code
    * @param string HTTP status text
    */
    public function setStatusCode($code, $name = NULL) {
    	$this->statusCode = $code;
    	$this->statusText = null !== $name ? $name : $this->httpStatus[$code];
  	}

    /**
     * Retrieves status code for the current web response.
     *
     * @return string Status code
     */
 	public function getStatusCode() {
    	return $this->statusCode;
  	}

   /**
    * Sets a HTTP header.
    *
    * @param string HTTP header name
    * @param string Value
    * @param boolean Replace for the value
    */
 	public function setHttpHeader($name, $value) {
  		$this->httpHeaders[$name] = $value;
	}

	/**
     * Gets HTTP header current value.
     *
     * @param string $name name of HTTP header
     * @return string Returns a HTTP header
     */
	public function getHttpHeader($name) {
		return $this->httpHeaders[$name];
  	}

  	/**
  	 * Removes all HTTP Headers registred so far
  	 *
  	 * @return void
  	 */
  	public function clearHttpHeaders() {
		$this->httpHeaders = array();  		
  	}
  	
  	/**
  	 * Checks if a HTTP Header is defined
  	 *
  	 * @param string $name
  	 * @return booelan $found returns true if header has been found
  	 */
  	public function hasHttpHeader($name) {
  		return isset($this->httpHeader[$name]);
  	}
  	
  	/**
  	 * Sets a response content type
  	 *
  	 * @param string $contentType content type to be set
  	 */
  	public function setContentType($contentType) {
  		$this->setHttpHeader('content-type', $contentType);
  	}
  	
  	/**
  	 * Gets current response content type
  	 * 
  	 * @return string $contentType current content type of this response
  	 */
  	public function getContentType() {
  		return $this->getHttpHeader('content_type');
  	}
  	
  	/**
  	 * Sends all headers to server
  	 * 
  	 * @return void
  	 */
  	public function sendHttpHeaders() {
  		header('HTTP/1.0 '. $this->statusCode . ' ' . $this->statusText);
  		foreach($this->httpHeaders as $name => $httpHeader) {
  			header($name . ': ' . $httpHeader);
  		}
  	}
  	
	/**
	 * Adds an external stylesheet to the HTML Header
	 *
	 * @param string $path
	 * @param string $media
	 */
	public function addStyleSheet($path, $media='') { 	      	
	    $options['href'] = $path;
	    $options['type'] = 'text/css';
	    $options['rel']  = 'stylesheet';
	    if ($media) $options['media'] = $media;
      	
      	$GLOBALS['TSFE']->additionalHeaderData[$this->controller->getExtension()].= tx_auxo_aui_helper::getTag('link', $options);
	}		
	
	/**
	 * Sets content of response
	 *
	 * @param string $content content
	 */
	public function setContent($content) {
		$this->content = $content;
	}
	
	/**
	 * Returns current context of this response
	 *
	 * @return string $content
	 */
	public function getContent() {
		return $this->content;
	}
	
	/**
	 * Sets name of current view
	 *
	 * @param string $viewname name of current view
	 */
	public function setView($viewname) {
		$this->viewname = $viewname;
	}
	
	/**
	 * Returns name of current view
	 *
	 * @return string $viewname name of current view
	 */
	public function getView() {
		return $this->viewname;
	}
	
	/**
	 * Sets and sends a cookie to the client
	 *
	 * @param string $name name of the cookie
	 * @param mixed $value value of the cookie
	 * @param long $maxage time of expiration
	 * @param string $path path
	 * @param string $domain web domain
	 * @param boolean $secure if true the cookie is sent via https
	 * @param boolean $HTTPonly if true the cookie is not available in javascript, etc. 
	 * @return boolean $sent returns true if cookie has been sent to the client
	 * @author isook@gmail.com
	 */
	public function setCookie($name, $value, $maxage=0, $path ='/', $domain='', $secure=false, $HTTPonly=false) {
	      $ob = ini_get('output_buffering'); 

        /* Abort the method if headers have already been sent, 
         * except when output buffering has been enabled 
    	 */    
		if (headers_sent() && (bool) $ob === false || strtolower($ob) == 'off') 
        	return false; 

        if (! empty($domain)) { 
            // Fix the domain to accept domains with and without 'www.'. 
            if ( strtolower( substr($domain, 0, 4) ) == 'www.' ) $domain = substr($domain, 4); 
            // Add the dot prefix to ensure compatibility with subdomains 
            if ( substr($domain, 0, 1) != '.' ) $domain = '.'.$domain; 

            // Remove port information. 
            $port = strpos($domain, ':'); 

            if ( $port !== false ) $domain = substr($domain, 0, $port); 
        } 

        // Prevent "headers already sent" error with utf8 support (BOM) 
        //if ( utf8_support ) header('Content-Type: text/html; charset=utf-8'); 

        header('Set-Cookie: '.rawurlencode($name).'='.rawurlencode($value) 
                                    .(empty($domain) ? '' : '; Domain='.$domain) 
                                    .(empty($maxage) ? '' : '; Max-Age='.$maxage) 
                                    .(empty($path) ? '' : '; Path='.$path) 
                                    .(!$secure ? '' : '; Secure') 
                                    .(!$HTTPOnly ? '' : '; HttpOnly'), false); 
        return true; 
	}
	
	/**
	 * Deletes and invalidates an existing cookie
	 *
	 * @param string $name name of the cookie
	 */
	public function deleteCookie($name) {
		$this->setCookie($name, '', time() - 3600, '/');		
		unset($_COOKIE[$name]);
	}
}
?>